#ifndef SH_SINGLETON_DYNAMICSINGLETON_HPP
#define SH_SINGLETON_DYNAMICSINGLETON_HPP

#include <mutex>

namespace sh {


template<class T>
struct DynamicSingleton {
    static T* getInstance();
    static void destroy();
private:
    static T* instance;
    static std::mutex mtx;
};


/*
* //////////////////////////////////////////////////////////////////////////////////////////
*
*
*
* //////////////////////////////////////////////////////////////////////////////////////////
*/


template<class T> T* DynamicSingleton<T>::instance = nullptr;
template<class T> std::mutex DynamicSingleton<T>::mtx;

template<class T>
inline T* DynamicSingleton<T>::getInstance()
{
    if(!instance) {
        std::lock_guard<std::mutex> lock(mtx);
        if(!instance) instance = new T;
    }
    return instance;
}

template<class T>
inline void DynamicSingleton<T>::destroy()
{
    if(!instance) return;
    std::lock_guard<std::mutex> lock(mtx);
    if(!instance) return;
    delete instance;
    instance = nullptr;
}



} // namespace sh

#endif // SH_SINGLETON_DYNAMICSINGLETON_HPP
